package hn.cch.async.controller;

import hn.cch.async.service.AsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

@RequestMapping(value = "/")
@RestController
public class AsyncController {

    private static final Logger logger = LoggerFactory.getLogger(AsyncController.class);

    @Autowired
    private AsyncService asyncService;

    /**
     * controller没有@Async，service使用@Async
     */
    @GetMapping(value = "/sync/Async")
    public void syncAsync() {
        logger.info("sync return void start");
        asyncService.async();
        logger.info("sync return void stop");
    }


    @GetMapping(value = "/sync/Async/Single")
    public String syncAsyncSingle(@RequestParam(value = "string") String string) {
        logger.info("sync Single start");

        // 单次执行异步任务
        Future<String> future = asyncService.async(string);
        String result = "null";
        try {
            // 阻塞等待执行结果
            result = future.get();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        logger.info("sync Single stop");
        return result;
    }


    @GetMapping(value = "/sync/Async/Number")
    public List<String> syncAsyncNumber(@RequestParam(value = "prefix") String prefix,
                                        @RequestParam(value = "number") Integer number) {
        logger.info("sync Number start");
        // 批量执行异步任务
        List<Future<String>> futureList = new ArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(number);
        for (int i = 0; i < number; i++) {
            futureList.add(asyncService.async(String.format("%s-%d", prefix, i), countDownLatch));
        }
        logger.info("async");
        List<String> resultList = new ArrayList<>();
        try {
            // 等待任务全部执行完成后获取所有结果
            countDownLatch.await();
            logger.info("await");
            for (Future<String> future : futureList) {
                // 阻塞等待执行结果
                resultList.add(future.get());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        logger.info("sync Number stop");
        return resultList;
    }


    /**
     * controller使用@Async，service没有@Async
     * 适用场景：触发后台处理数据
     */
    @Async
    @GetMapping(value = "/async/Sync")
    public void asyncSync() {
        logger.info("async sync return void start");
        asyncService.sync();
        logger.info("async sync return void stop");

    }


    /**
     * controller使用@Async，service没有@Async
     * 经过测试这种使用场景得不到返回结果
     *
     */
    @Async
    @GetMapping(value = "async/Sync/Future")
    public Future<String> asyncSyncFuture(@RequestParam(value = "string") String string) {
        logger.info("async sync return Future start");
        Future<String> future = asyncService.sync(string);
        try {
            // 阻塞等待执行结果
            while (!future.isDone()){
                asyncService.run(1);
            }
            logger.info("future.get():{}", future.get());
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        logger.info("async sync return Future stop");
        return future;
    }

}
